#include "DomTreeProperties.h"
#include "DomTypeMap.h"

#include <QDebug>

static DomTypeMap sDomTypeMap;

NodeTextFactory::NodeTextFactory(NodeTextProperty textProp)
    : mNodeTextProp(textProp)
{
}

QString NodeTextFactory::displayText(const QDomNode &node, bool flatTextElements)
{
    QString text;
    switch(mNodeTextProp.eTextProp)
    {
    case NO_TEXT: break;
    case NODE_NAME:
    {
        text = node.nodeName();
    }break;
    case NODE_VALUE:
    {

        if(flatTextElements && node.isElement())
        {
            if(node.childNodes().size() == 1
                    && node.childNodes().at(0).nodeType() == QDomNode::TextNode)
            {
                text = node.childNodes().at(0).nodeValue();
            }
            else
            {
                text = node.nodeValue();
            }
        }
        else
        {
            text = node.nodeValue();
        }
    }break;
    case NODE_TYPE:
    {
        // Convert node type to string
        text = sDomTypeMap.nodeTypeToString(node.nodeType());
    }break;
    case ATTR_VALUE:
    {
        if(node.isElement() && !mNodeTextProp.propPrams.empty())
        {
            text = node.toElement().attribute(mNodeTextProp.propPrams[0]);
        }
    }break;
    case ATTR_NAME_VALUE:
    {
        if(node.isElement() && !mNodeTextProp.propPrams.empty())
        {
            text = node.toElement().attribute(mNodeTextProp.propPrams[0]);
            if(!text.isEmpty())
            {
                text = mNodeTextProp.propPrams[0] + "=\""
                        + text + "\"";
            }
        }
    }break;
    default: break;
    }
    return text;
}

NodeIconFactory::NodeIconFactory(NodeIconProperty prop)
    : mNodeIconProp(prop)
{

}

QIcon NodeIconFactory::displayIcon(const QDomNode &node)
{
    switch(mNodeIconProp.eIconProp)
    {
    case NO_ICON: break;
    case NODE_TYPE_ICON:
    {
        if(node.isElement())
            return QIcon(":/icons/element.png");

        if(node.isAttr())
            return QIcon(":/icons/attribute.PNG");

        if(node.isText())
            return QIcon(":/icons/text.png");
    }break;
    case MANUAL_ICON:
    {
        return QIcon(mNodeIconProp.propPrams[0]);
    }break;
    case TAG_NAME_AUTO_ICON:
    {

    }break;
    default: break;
    }
    return QIcon();
}



DomTreeProperties::DomTreeProperties()
    : mFlatTextElements(false)
{
    // Node type visibility
    mNodeTypeVisibleMap[QDomNode::ElementNode] = true;
    mNodeTypeVisibleMap[QDomNode::AttributeNode] = true;
    mNodeTypeVisibleMap[QDomNode::TextNode] = true;
    mNodeTypeVisibleMap[QDomNode::CDATASectionNode] = true;
    mNodeTypeVisibleMap[QDomNode::EntityReferenceNode] = true;
    mNodeTypeVisibleMap[QDomNode::EntityNode] = true;
    mNodeTypeVisibleMap[QDomNode::ProcessingInstructionNode] = true;
    mNodeTypeVisibleMap[QDomNode::CommentNode] = true;
    mNodeTypeVisibleMap[QDomNode::DocumentNode] = true;
    mNodeTypeVisibleMap[QDomNode::DocumentTypeNode] = true;
    mNodeTypeVisibleMap[QDomNode::DocumentFragmentNode] = true;
    mNodeTypeVisibleMap[QDomNode::NotationNode] = true;
    mNodeTypeVisibleMap[QDomNode::BaseNode] = true;
    mNodeTypeVisibleMap[QDomNode::CharacterDataNode] = true;

    setHeaderLabel(0 , "Node Name");
    setHeaderLabel(1 , "Node Value");
    //setHeaderLabel(2 , "Node Type");
    // setHeaderLabel(2 , "name");
//    setHeaderLabel(3 , "class");

    setTextProperty(0, NODE_TYPE_DEFAULT, NODE_NAME);
    setTextProperty(1, NODE_TYPE_DEFAULT, NODE_VALUE);
    //setTextProperty(2, NODE_TYPE_DEFAULT, NODE_TYPE);
//    setTextProperty(2, QDomNode::ElementNode,
                    //NodeTextProperty(ATTR_VALUE, QStringList(QString("name"))));
//    setTextProperty(3, QDomNode::ElementNode,
//                    NodeTextProperty(ATTR_VALUE, QStringList(QString("class"))));

    setIconProperty(0, NODE_TYPE_DEFAULT, NODE_TYPE_ICON);
//    setIconProperty(1, NODE_TYPE_DEFAULT,
//                    NodeIconProperty(MANUAL_ICON, QStringList(QString(":/icons/open.png"))));
}

DomTreeProperties::~DomTreeProperties()
{

}

void DomTreeProperties::setHeaderLabel(int column, QString text)
{
    // Append empty columns if column < mHeaderLabels size
    int colCnt = mHeaderLabels.size();
    for(int i = column; i <= colCnt; i++)
    {
        addColumn();
    }
    // Set label
    mHeaderLabels[column] = text;
}

void DomTreeProperties::setTextProperty(int column, int type,
                     NodeTextProperty prop)
{
    // Append empty columns if column < mNodeTextMapList size
    int colCnt = mHeaderLabels.size();
    for(int i = column; i <= colCnt; i++)
    {
        addColumn();
    }
    // Text factory exists for type?
    if(!mNodeTextMapList[column].contains(type))
    {
        // Create new factory
        mNodeTextMapList[column][type] = new NodeTextFactory(prop);
    }
    else
    {
        // Set property for column/type
        mNodeTextMapList[column][type]->setTextProperty(prop);
    }
}

void DomTreeProperties::setIconProperty(int column, int type,
                     NodeIconProperty prop)
{
    // Append empty columns if column < mNodeIconMapList size
    int colCnt = mHeaderLabels.size();
    for(int i = column; i <= colCnt; i++)
    {
        addColumn();
    }
    // Icon factory exists for type?
    if(!mNodeIconMapList[column].contains(type))
    {
        // Create new factory
        mNodeIconMapList[column][type] = new NodeIconFactory(prop);
    }
    else
    {
        // Set property for column/type
        mNodeIconMapList[column][type]->setIconProperty(prop);
    }
}

void DomTreeProperties::setNodeTypeVisible(QDomNode::NodeType type, bool visible)
{
    mNodeTypeVisibleMap[type] = visible;
}

bool DomTreeProperties::nodeTypeVisible(QDomNode::NodeType type)
{
    if(mNodeTypeVisibleMap.contains(type))
        return mNodeTypeVisibleMap[type];
    else
        return false;
}

QString DomTreeProperties::nodeDisplayText(int column, const QDomNode &node)
{
    // Column exceeds column count?
    if(column > mNodeTextMapList.size()-1)
        return QString();

    // If there is no text property defined return default
    if(!mNodeTextMapList[column].contains(node.nodeType()))
        return mNodeTextMapList[column][NODE_TYPE_DEFAULT]->displayText(node, mFlatTextElements);

    // Return text depending on cloumn/type settings
    return mNodeTextMapList[column][node.nodeType()]->displayText(node, mFlatTextElements);
}

QIcon DomTreeProperties::nodeDisplayIcon(int column, const QDomNode &node)
{
    // Column exceeds column count?
    if(column > mNodeIconMapList.size()-1)
        return QIcon();

    // If there is no Icon property defined return default
    if(!mNodeIconMapList[column].contains(node.nodeType()))
        return mNodeIconMapList[column][NODE_TYPE_DEFAULT]->displayIcon(node);

    // Return Icon depending on cloumn/type settings
    return mNodeIconMapList[column][node.nodeType()]->displayIcon(node);
}


void DomTreeProperties::addColumn()
{
    // Add empty header label
    mHeaderLabels.append(QString());

    // Add default column with display property NO_TEXT
    tNodeTextMap textMap;
    NodeTextFactory *textFactory = new NodeTextFactory(NodeTextProperty(NO_TEXT));
    textMap[NODE_TYPE_DEFAULT] = textFactory;
    mNodeTextMapList.append(textMap);

    // Add default column with diplay property NO_ICON
    tNodeIconMap iconMap;
    NodeIconFactory *iconFactory = new NodeIconFactory(NodeIconProperty(NO_ICON));
    iconMap[NODE_TYPE_DEFAULT] = iconFactory;
    mNodeIconMapList.append(iconMap);
}
